// 《围棋》作者版权所有。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package ssa

import (
	"cmd/internal/obj"
	"sort"
)

// 缓存保存可重用的编译器状态。
// 它打算重新用于多个Func编译。
type Cache struct {
	// 用于低编号值和块的存储。
	values [2000]Value
	blocks [200]Block
	locs   [2000]Location

	// 可重复使用的stackAllocState。
	// 参见stackalloc。go's{new，put}StackAllocState。
	stackAllocState *stackAllocState

	domblockstore []ID         // 计算支配者的暂存空间
	scrSparseSet  []*sparseSet // 要重新使用的暂存稀疏集。
	scrSparseMap  []*sparseMap // 重新使用稀疏贴图。
	scrPoset      []*poset     // 要重用的scratch偏序集
	// 死码包含专门用于死码传递的可重用切片。
	// 由于它的运行频率，它得到了特殊的处理。
	deadcode struct {
		liveOrderStmts []*Value
		live           []bool
		q              []*Value
	}
	// 可重复使用的regalloc状态。
	regallocValues []valState

	ValueToProgAfter []*obj.Prog
	debugState       debugState

	Liveness interface{} // /*gc。livenessFuncCache 
}

func (c *Cache) Reset() {
	nv := sort.Search(len(c.values), func(i int) bool { return c.values[i].ID == 0 })
	xv := c.values[:nv]
	for i := range xv {
		xv[i] = Value{}
	}
	nb := sort.Search(len(c.blocks), func(i int) bool { return c.blocks[i].ID == 0 })
	xb := c.blocks[:nb]
	for i := range xb {
		xb[i] = Block{}
	}
	nl := sort.Search(len(c.locs), func(i int) bool { return c.locs[i] == nil })
	xl := c.locs[:nl]
	for i := range xl {
		xl[i] = nil
	}

	// regalloc将c.RegallocValue的长度设置为它可能使用的任何值，
	// 根据长度如此清晰。
	for i := range c.regallocValues {
		c.regallocValues[i] = valState{}
	}

	// liveOrderStmts在编译函数时被多次使用。
	// 我们不知道高水位线在哪里，所以请重新设定上限并搜索。
	c.deadcode.liveOrderStmts = c.deadcode.liveOrderStmts[:cap(c.deadcode.liveOrderStmts)]
	no := sort.Search(len(c.deadcode.liveOrderStmts), func(i int) bool { return c.deadcode.liveOrderStmts[i] == nil })
	xo := c.deadcode.liveOrderStmts[:no]
	for i := range xo {
		xo[i] = nil
	}
	c.deadcode.q = c.deadcode.q[:cap(c.deadcode.q)]
	nq := sort.Search(len(c.deadcode.q), func(i int) bool { return c.deadcode.q[i] == nil })
	xq := c.deadcode.q[:nq]
	for i := range xq {
		xq[i] = nil
	}
}
